import { _decorator, Component, Node, EventTarget } from 'cc'
import { DynamicTasks } from "run-time-opti"
import { Logger, request } from './utils'
import { Chapter } from './store'
import { FrameEvents, FrameType, ServiceName } from '../enum'
import { ServiceLocator } from './utils/locator'
import { BGPFrame, SpineFrame, TextFrame } from './frames'
import { BGMFrame } from './frames/BGMFrame'
const { ccclass, property } = _decorator

@ccclass('scene')
export class scene extends Component {

    @property(BGPFrame)
    BGPFrame: BGPFrame

    @property(SpineFrame)
    SpineFrame: SpineFrame

    @property(TextFrame)
    TextFrame: TextFrame

    @property(BGMFrame)
    BGMFrame: BGMFrame

    chapter?: Chapter


    #services = ServiceLocator;
    #events = new EventTarget();
    #tasks = new DynamicTasks();
    #log = new Logger('场景');

    #nextLock = false;


    async start() {
        this.#log.debug('开始')
        this.#services.register(ServiceName.Event, this.#events)
        this.#services.register(ServiceName.Task, this.#tasks)
        this.inspect()

        const { status, data } = await request.post<LDAPI.Response<LDChapter.ChapterResponse>>('api/v1/book/preview').json()
        if (status == 200) {
            this.#log.debug('章节数据', data)
            this.chapter = new Chapter(data.dataJson)
            this.#services.register(ServiceName.Chapter, this.chapter)
            this.chapter.currentFrameId = this.chapter.chapter.frames.structure[0].id
            this.nextFrame()
        }
    }

    inspect() {
        this.#events.on(FrameEvents.frameLock, (state: boolean) => {
            this.#nextLock = state
        })
        this.#events.on(FrameEvents.stepNext, () => {
            this.#log.debug('进入下一帧')
            this.stepNext()
        })
    }

    protected onDestroy(): void {
        this.#events.removeAll(FrameEvents.frameLock)
        this.#events.removeAll(FrameEvents.stepNext)
    }

    stepNext() {
        this.#log.debug('下一步', this.#nextLock)
        if (this.#nextLock) return
        this.#nextLock = true
        this.chapter.currentFrameId = this.chapter.next()
        this.nextFrame()
    }

    nextFrame() {
        this.#log.debug('进入下一帧 %o', this.chapter.currentFrame)
        if ('type' in this.chapter.currentFrame.content && this.chapter.currentFrame.content.type in this.frameHandle) {
            this.frameHandle[this.chapter.currentFrame.content.type](this.chapter.currentFrame)
        } else {
            this.#log.warn('未处理的帧类型 %o', this.chapter.currentFrame.content)
        }
    }

    frameHandle = {
        [FrameType.BGP]: this.handleBGPFrame.bind(this),
        [FrameType.SPINE]: this.handleSpineFrame.bind(this),
        [FrameType.TEXT]: this.handleTextFrame.bind(this),
    }


    async handleBGPFrame(frame: LDChapter.Frame) {
        this.#log.debug('处理背景帧 %o', frame.content)
        await this.TextFrame.clear()
        this.BGPFrame.run(frame.content as LDContent.BGPContent)
    }

    handleSpineFrame(frame: LDChapter.Frame) {
        this.#log.debug('处理spine帧 %o', frame.content)
        this.SpineFrame.run(frame.content as LDContent.SpineContent)
    }

    handleTextFrame(frame: LDChapter.Frame) {
        this.#log.debug('处理对话帧 %o', frame.content)
        this.TextFrame.run(frame.content as LDContent.DialogContent)
    }

}


